//
//  Zilla.m
//  Zilla
//
//  Created by Fanty on 13-12-26.
//  Copyright (c) 2013年 Fanty. All rights reserved.
//

#import "Zilla.h"
#import "UIDevice+IdentifierAddition.h"
#import "ZillaAccessData.h"
#import "ZillaUrlScheme.h"
#import "AsyncRequestWorkGroup.h"
#import "ChamleonFormDataRequest.h"
#import "AppValidateParser.h"
#import "AppValidate.h"
#import "AppInfoModel.h"
#import "AppInfoParser.h"
#import "LoginParser.h"
#import "SnapshotParser.h"
#import "ModuleParser.h"
#import "MessageParser.h"
#import "PriviligeParser.h"

#define PRODUCT_SCHEMESUFFIX @"115.28.1.119:18860"

@interface Zilla()

@property(nonatomic,strong) AsyncRequestWorkGroup* checkAppVaildateTask;
@property(nonatomic,strong) AsyncRequestWorkGroup* checkAppVersionTask;
@property(nonatomic,strong) AsyncRequestWorkGroup* loginTask;
@property(nonatomic,strong) AsyncRequestWorkGroup* moduleTask;
@property(nonatomic,strong) AsyncRequestWorkGroup* snapShotTask;
@property(nonatomic,strong) AsyncRequestWorkGroup* syncReceiptsTask;
@property(nonatomic,strong) AsyncRequestWorkGroup* feedbakTask;
@property(nonatomic,strong) AsyncRequestWorkGroup* rolePriviligesListTask;

//生成http 到解析结果的异步
-(AsyncRequestWorkGroup*)asyncWithOperation:(ChamleonHTTPRequest*)operation parser:(JSONParser*)parser;

//建立带参数的post 请求
-(ChamleonFormDataRequest*)requestWithURL:(NSURL*)url;

@end

@implementation Zilla{
}

@synthesize zillAccessData;
@synthesize zillaUrlScheme;

-(id)initWithZillAccessData:(ZillaAccessData*)_zillAccessData{
    self=[super init];
    if(self){
        zillAccessData=_zillAccessData;
        zillaUrlScheme=[[ZillaUrlScheme alloc] init];
        zillaUrlScheme.zillaAccessData=zillAccessData;
    }
    return self;
}

-(id)initWithAppKey:(NSString*)_appKey appSecret:(NSString*)_appSecret sandBoxEnviroment:(BOOL)sandBoxEnviroment{
    self=[self initWithAppKey:_appKey appSecret:_appSecret sandBoxEnviroment:sandBoxEnviroment urlSchemeSuffix:PRODUCT_SCHEMESUFFIX];
    if(self){
    }
    return self;
}

-(id)initWithAppKey:(NSString*)_appKey appSecret:(NSString*)_appSecret sandBoxEnviroment:(BOOL)sandBoxEnviroment urlSchemeSuffix:(NSString*)_urlSchemeSuffix{
    self=[super init];
    if(self){
        zillAccessData=[[ZillaAccessData alloc] init];
        zillAccessData.appKey=_appKey;
        zillAccessData.appSecret=_appSecret;
        zillAccessData.urlSchemeSuffix=_urlSchemeSuffix;
        zillAccessData.sandBoxEnviroment=sandBoxEnviroment;
        zillaUrlScheme=[[ZillaUrlScheme alloc] init];
        zillaUrlScheme.zillaAccessData=zillAccessData;
    }
    return self;
}

- (void)dealloc{
    self.delegate=nil;
    [self cancelAllWorkGroup];
}

-(void)cancelAllWorkGroup{
    [self cancelCheckAppValidate];
    [self cancelCheckAppVersion];
    [self cancelLogin];
    [self cancelSyncModules];
    [self cancelSnapshot];
    [self cancelSyncReceipts];
    [self cancelFeedBack];
    [self cancelRolePriviligesListTask];

}

-(void)cancelCheckAppValidate{
    [self.checkAppVaildateTask cancel];
    self.checkAppVaildateTask=nil;
}

-(void)cancelCheckAppVersion{
    [self.checkAppVersionTask cancel];
    self.checkAppVersionTask=nil;

}

-(void)cancelLogin{
    [self.loginTask cancel];
    self.loginTask=nil;

}

-(void)cancelSyncModules{
    [self.moduleTask cancel];
    self.moduleTask=nil;
}

-(void)cancelSnapshot{
    [self.snapShotTask cancel];
    self.snapShotTask=nil;
}

-(void)cancelSyncReceipts{
    [self.syncReceiptsTask cancel];
    self.syncReceiptsTask=nil;
    
}

-(void)cancelFeedBack{
    [self.feedbakTask cancel];
    self.feedbakTask=nil;
    
}

-(void)cancelRolePriviligesListTask{
    [self.rolePriviligesListTask cancel];
    self.rolePriviligesListTask=nil;
}


-(AsyncRequestWorkGroup*)asyncWithOperation:(ChamleonHTTPRequest*)operation parser:(JSONParser*)parser{
    AsyncRequestWorkGroup* task=[[AsyncRequestWorkGroup alloc] init];
    task.request=operation;
    task.parser=parser;
    [task start];
    return task;
}


-(ChamleonFormDataRequest*)requestWithURL:(NSURL*)url{
    ChamleonFormDataRequest* request=[ChamleonFormDataRequest requestWithURL:url];
    [request setPostValue:zillAccessData.appKey forKey:@"appKey"];
    [request setPostValue:[[UIDevice currentDevice] uniqueDeviceIdentifier] forKey:@"deviceId"];
    [request setPostValue:[[NSBundle mainBundle] bundleIdentifier] forKey:@"appId"];
    [request setPostValue:zillAccessData.appToken forKey:@"token"];
    request.timeOutSeconds=10.0f;
    request.persistentConnectionTimeoutSeconds=10.0f;
    return request;
}


-(void)checkAppVaildate{
    [self cancelCheckAppValidate];
    ChamleonFormDataRequest* request=[ChamleonFormDataRequest requestWithURL:[zillaUrlScheme appCheckClient]];
    [request setPostValue:zillAccessData.appKey forKey:@"appKey"];
    [request setPostValue:zillAccessData.appSecret forKey:@"secret"];
    
    self.checkAppVaildateTask=[self asyncWithOperation:request parser:[[AppValidateParser alloc] init]];
    __block AsyncRequestWorkGroup* __task=self.checkAppVaildateTask;
    __block Zilla* objSelf=self;
    __block ZillaAccessData* __zillaAccessData=zillAccessData;
    [self.checkAppVaildateTask setFinishBlock:^{
        objSelf.checkAppVaildateTask=nil;
        if([__task result]!=nil){
            AppValidate* validate=[__task result];
            __zillaAccessData.appToken=validate.token;
            __zillaAccessData.appTokeExpired=validate.expired;
            if([objSelf.delegate respondsToSelector:@selector(authorSuccess)])
                [objSelf.delegate authorSuccess];
        }
        else{
            if([objSelf.delegate respondsToSelector:@selector(authorFailed:errorMessage:)])
                [objSelf.delegate authorFailed:[__task statusCode] errorMessage:[__task errorMessage]];
        }
    }];
}



-(AsyncRequestWorkGroup*)checkAppVersionWithWorkGroup{
    ChamleonHTTPRequest* request=[ChamleonHTTPRequest requestWithURL:[zillaUrlScheme appVersionCheck]];
    request.timeOutSeconds=10.0f;
    request.persistentConnectionTimeoutSeconds=10.0f;
    AsyncRequestWorkGroup* task=[self asyncWithOperation:request parser:[[AppInfoParser alloc] init]];
    return task;
}

-(void)checkAppVersion{
    [self cancelCheckAppVersion];
    self.checkAppVersionTask=[self checkAppVersionWithWorkGroup];
    __block AsyncRequestWorkGroup* __task=self.checkAppVersionTask;
    __block Zilla* objSelf=self;
    __block ZillaUrlScheme* __zillaUrlScheme=zillaUrlScheme;

    [self.checkAppVersionTask setFinishBlock:^{
        objSelf.checkAppVersionTask=nil;
        
        AppInfoModel* model=[__task result];
        if(model!=nil){
            NSString* downloadUrl=[[__zillaUrlScheme attachmentByIdURL:model.plist] absoluteString];
            model.downloadURL=[__zillaUrlScheme applicationNewVersionLink:downloadUrl];
            if([objSelf.delegate respondsToSelector:@selector(appVersionChecked:)])
                [objSelf.delegate appVersionChecked:model];

        }
        else{
            if([objSelf.delegate respondsToSelector:@selector(appVersionFailed:errorMessage:)])
                [objSelf.delegate appVersionFailed:[__task statusCode] errorMessage:[__task errorMessage]];

        }
    }];
}


-(void)registerDevice:(NSString*)deviceToken accountName:(NSString*)accountName  roleName:(NSString*)roleName{

    NSMutableString* str=[[NSMutableString alloc] initWithCapacity:2];
    [str appendString:@"{"];
    [str appendFormat:@"\"%@\":\"%@\",",@"deviceId",[[UIDevice currentDevice] uniqueDeviceIdentifier]];
    [str appendFormat:@"\"%@\":\"%@\",",@"appId",zillAccessData.appKey];
    [str appendFormat:@"\"%@\":\"%@\",",@"pushToken",deviceToken];
    
    if(zillAccessData.sandBoxEnviroment)
        [str appendFormat:@"\"%@\":\"%@\",",@"channelId",@"apns_sandbox"];
    else
        [str appendFormat:@"\"%@\":\"%@\",",@"channelId",@"apns"];
    
    [str appendFormat:@"\"%@\":\"%@\",",@"deviceName",[[[UIDevice currentDevice] name] stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]];
    [str appendFormat:@"\"%@\":\"%@\",",@"osName",@"IOS"];
    [str appendFormat:@"\"%@\":\"%@\",",@"build",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]];
    
    [str appendFormat:@"\"%@\":\"%@\",",@"osVersion",[[UIDevice currentDevice]systemVersion]];

    [str appendFormat:@"\"%@\":\"%@\",",@"alias",([accountName length]>0?accountName:@"")];

    [str appendString:@"\"tags\":["];
    [str appendString:@"{"];
    [str appendFormat:@"\"key\":\"role\",\"value\":\"%@\"",([roleName length]>0?roleName:@"")];
    [str appendString:@"}"];
    [str appendString:@"]"];
    [str appendString:@"}"];
    
    NSData* data=[str dataUsingEncoding:NSUTF8StringEncoding];
    ChamleonHTTPRequest *request = [ChamleonHTTPRequest requestWithURL:[zillaUrlScheme deviceRegisterURL]];
    request.timeOutSeconds=10.0f;
    [request setPersistentConnectionTimeoutSeconds:10.0f];
    [request appendPostData:data];
    [request setRequestMethod:@"PUT"];
    
    AsyncRequestWorkGroup* task=[self asyncWithOperation:request parser:nil];
    __block AsyncRequestWorkGroup* __task=task;
    __block Zilla* objSelf=self;
    
    [task setFinishBlock:^{
        if([objSelf.delegate respondsToSelector:@selector(registerDeviceFinish:)])
            [objSelf.delegate registerDeviceFinish:(__task.errorCode==0)];

    }];
}


-(void)login:(NSString*)name password:(NSString*)password{
    [self cancelLogin];
    self.loginTask=[self loginWithWorkGroup:name password:password];
    __block AsyncRequestWorkGroup* __task=self.loginTask;
    __block Zilla* objSelf=self;

    [self.loginTask setFinishBlock:^{
        objSelf.loginTask=nil;
        if([__task result]!=nil){
            if([objSelf.delegate respondsToSelector:@selector(loginSuccess:)])
                [objSelf.delegate loginSuccess:[__task result]];

        }
        else{
            if([objSelf.delegate respondsToSelector:@selector(loginFailed:errorMessage:)])
                [objSelf.delegate loginFailed:[__task statusCode] errorMessage:[__task errorMessage]];
        }
    }];
    
}


-(AsyncRequestWorkGroup*)loginWithWorkGroup:(NSString*)name password:(NSString*)password{
    ChamleonFormDataRequest *request = [self requestWithURL:[zillaUrlScheme loginURL]];
    request.timeOutSeconds=20.0f;
    [request setPersistentConnectionTimeoutSeconds:20.0f];
    [request setPostValue:name forKey:@"username"];
    [request setPostValue:password forKey:@"password"];
    
    return [self asyncWithOperation:request parser:[[LoginParser alloc] init]];

}

-(AsyncRequestWorkGroup*)syncModulesWithWorkGroup{
    ChamleonHTTPRequest *request = [ChamleonHTTPRequest requestWithURL:[zillaUrlScheme moduleListURL]];
    request.timeOutSeconds=10.0f;
    [request setPersistentConnectionTimeoutSeconds:10.0f];
    ModuleParser* parser=[[ModuleParser alloc] init];
    return [self asyncWithOperation:request parser:parser];
}

-(void)syncModules{
    [self cancelSyncModules];
    self.moduleTask=[self syncModulesWithWorkGroup];
    __block AsyncRequestWorkGroup* __task=self.moduleTask;
    __block Zilla* objSelf=self;
    
    [self.moduleTask setFinishBlock:^{
        objSelf.moduleTask=nil;
        if([__task result]!=nil){
            if([objSelf.delegate respondsToSelector:@selector(syncModulesSuccess:)])
            [objSelf.delegate syncModulesSuccess:[__task result]];
        }
        else{
            
            if([__task statusCode]==403){
                
                if([objSelf.delegate respondsToSelector:@selector(authorExpired)])
                    [objSelf.delegate authorExpired];

            }
            else{
                
                if([objSelf.delegate respondsToSelector:@selector(syncModulesFailed:errorMessage:)])
                    [objSelf.delegate syncModulesFailed:[__task statusCode] errorMessage:[__task errorMessage]];
                
            }
        }
        
    }];
}

-(void)snapshot:(NSString*)identifier version:(NSString*)version{
    [self cancelSnapshot];
    
    self.snapShotTask=[self snapshotWithWorkGroup:identifier version:version];
    __block AsyncRequestWorkGroup* __task=self.snapShotTask;
    __block Zilla* objSelf=self;
    
    [self.snapShotTask setFinishBlock:^{
        objSelf.snapShotTask=nil;
        if([__task result]!=nil){
            if([objSelf.delegate respondsToSelector:@selector(snapshotSuccess:)])
            [objSelf.delegate snapshotSuccess:[__task result]];
        }
        else{
            if([objSelf.delegate respondsToSelector:@selector(snapshotFailed:errorMessage:)])
            [objSelf.delegate snapshotFailed:[__task statusCode] errorMessage:[__task errorMessage]];
        }
    }];
}

-(AsyncRequestWorkGroup*)snapshotWithWorkGroup:(NSString*)identifier version:(NSString*)version{
    ChamleonHTTPRequest* request=[ChamleonHTTPRequest requestWithURL:[zillaUrlScheme snapshotURL:identifier version:version]];
    
    return [self asyncWithOperation:request parser:[[SnapshotParser alloc] init]];
}

-(void)syncReceipts{
    [self cancelSyncReceipts];
    self.syncReceiptsTask=[self syncReceiptsWithWorkGroup];
    __block AsyncRequestWorkGroup* __task=self.syncReceiptsTask;
    __block Zilla* objSelf=self;
    
    [self.syncReceiptsTask setFinishBlock:^{
        objSelf.syncReceiptsTask=nil;
        if([__task result]!=nil){
            if([objSelf.delegate respondsToSelector:@selector(syncReceiptsSuccess:)])
            [objSelf.delegate syncReceiptsSuccess:[__task result]];
        }
        else{
            if([objSelf.delegate respondsToSelector:@selector(syncReceiptsFailed:errorMessage:)])
            [objSelf.delegate syncReceiptsFailed:[__task statusCode] errorMessage:[__task errorMessage]];
        }
        
    }];
    
}

-(AsyncRequestWorkGroup*)syncReceiptsWithWorkGroup{
    ChamleonHTTPRequest* request=[ChamleonHTTPRequest requestWithURL:[zillaUrlScheme messageListURL]];
    return [self asyncWithOperation:request parser:[[MessageParser alloc] init]];
}


-(void)syncReceiptsWithMessageId:(NSString*)messageId{
    [self cancelSyncReceipts];
    self.syncReceiptsTask=[self syncReceiptsWithMessageIdWithWorkGroup:messageId];
    __block AsyncRequestWorkGroup* __task=self.syncReceiptsTask;
    __block Zilla* objSelf=self;
    
    [self.syncReceiptsTask setFinishBlock:^{
        objSelf.syncReceiptsTask=nil;
        if([__task result]!=nil){
            if([objSelf.delegate respondsToSelector:@selector(syncReceiptsSuccess:)])
            [objSelf.delegate syncReceiptsSuccess:[__task result]];
        }
        else{
            if([objSelf.delegate respondsToSelector:@selector(syncReceiptsFailed:errorMessage:)])
            [objSelf.delegate syncReceiptsFailed:[__task statusCode] errorMessage:[__task errorMessage]];
        }
        
    }];
    
}

-(AsyncRequestWorkGroup*)syncReceiptsWithMessageIdWithWorkGroup:(NSString*)messageId{
    ChamleonHTTPRequest* request=[ChamleonHTTPRequest requestWithURL:[zillaUrlScheme messageByIdURL:messageId]];
    return [self asyncWithOperation:request parser:[[MessageParser alloc] init]];
}

-(void)feedBackReceipt:(NSArray*)array{
    [self cancelFeedBack];
    
    NSMutableString* ids=[[NSMutableString alloc] initWithCapacity:2];
    [array enumerateObjectsUsingBlock:^(id obj,NSUInteger index,BOOL*stop){
        NSString* messageId=obj;
        [ids appendString:messageId];
        if(index<[array count]-1)
        [ids appendString:@","];
    }];
    
    ChamleonFormDataRequest* request=[ChamleonFormDataRequest requestWithURL:[zillaUrlScheme receptURL]];
    [request setPostValue:zillAccessData.appKey forKey:@"appKey"];
    [request setPostValue:[[UIDevice currentDevice] uniqueDeviceIdentifier] forKey:@"deviceId"];
    
    request.timeOutSeconds=5.0f;
    request.persistentConnectionTimeoutSeconds=5.0f;
    
    [request setPostValue:ids  forKey:@"msgId"];
    [request setPostValue:zillAccessData.appKey forKey:@"appId"];
    [request setRequestMethod:@"PUT"];
    
    self.feedbakTask=[self asyncWithOperation:request parser:nil];
    
    __block Zilla* objSelf=self;
    [self.feedbakTask setFinishBlock:^{
        objSelf.feedbakTask=nil;
        if([objSelf.delegate respondsToSelector:@selector(feedBackCallBack)])
        [objSelf.delegate feedBackCallBack];
    }];
}

//获取角色权限列表
-(void)rolePriviligesList:(NSString*)accountName{
    [self cancelRolePriviligesListTask];
    self.rolePriviligesListTask=[self rolePriviligesListWithWorkGroup:accountName];
    __block AsyncRequestWorkGroup* __task=self.rolePriviligesListTask;
    __block Zilla* objSelf=self;
    
    [self.rolePriviligesListTask setFinishBlock:^{
        objSelf.rolePriviligesListTask=nil;
        
        if([__task result]!=nil){
            if([objSelf.delegate respondsToSelector:@selector(rolePriviligesListSuccess:)])
                [objSelf.delegate rolePriviligesListSuccess:[__task result]];
            
        }
        else{
            if([objSelf.delegate respondsToSelector:@selector(rolePriviligesListFailed:errorMessage:)])
                [objSelf.delegate rolePriviligesListFailed:[__task statusCode] errorMessage:[__task errorMessage]];
        }
    }];

}

-(AsyncRequestWorkGroup*)rolePriviligesListWithWorkGroup:(NSString*)accountName{
    
    
    ChamleonHTTPRequest* request=[ChamleonHTTPRequest requestWithURL:[zillaUrlScheme rolePriviligesURL:accountName]];
    
    return [self asyncWithOperation:request parser:[[PriviligeParser alloc] init]];

}


@end
